/*****************************************************************************//*!
* file  : systask.c
* creat : apleilx
* note :  除初始化外，禁止该任务及其子程序使用含有阻塞的功能，包括数据存储，USB操作等等
* data  : 2019/07/02
*******************************************************************************/
#include "bsp.h"
#include "os_obj.h"
#include "systask.h"

#include "flashtoeep.h"
#include "common.h"

void feep_erase(uint32_t addr);
void feep_program(uint32_t addr, uint32_t dat);
void feep_unlock(void);
void feep_lock(void);

uint8_t ExtEepErase(uint32_t AddrBase);             /*从指定地址擦除，Nums指定擦除的扇区个数*/
uint8_t ExtEepProgram(uint32_t Addr, uint8_t *Data, uint16_t Len); /*向指定指定地址编程数据*/
uint8_t ExtEepRead(uint32_t Addr, uint8_t *Data, uint16_t Len);    /*读取块数据*/

struct
{
	uint16_t dat[32];
	uint16_t dat_start;
	uint16_t read_req;
	uint16_t save_req;
	uint16_t m_read_req;
	uint16_t m_save_req;
} eep_obj;

ExtFlashEepInfo_Type ext_eep_info;
const ExtFlashEepCfg_Type ext_eep_cfg = 
{
	.EepBase = 0x60000,
	.EepSize = 20 * 1024,
	.SectorSize = 4*1024,
	.DataBlockSize = 32,
	.DataSize = 22,
	.Data = eep_obj.dat,
	.Info = &ext_eep_info,
	.Erase = ExtEepErase,
	.Program = ExtEepProgram,
	.Read = ExtEepRead,
};

FlashEepInfo_Type m_fe_info;
const FlashEepCfg_Type mfe_cfg =
{
	.EepBase = 0x68000,
	.EepSize = 20 * 1024,
	.SectorSize = 4 * 1024,
	.DataBlockSize = 32,
	.DataSize = 22,
	.Data = eep_obj.dat,
	.Info = & m_fe_info,
	.Erase = feep_erase,
	.Program = feep_program,
	.Unlock = feep_unlock,
	.Lock = feep_lock,
};


void Eep_Test(void)
{
	ExtFlashMulEepRead(&ext_eep_cfg);
	
	FlashMulEepRead(&mfe_cfg);
	
	while(1)
	{
		if(sys_st.str_module != 6)
			break;
		
		if(eep_obj.read_req)
		{
			ExtFlashMulEepRead(&ext_eep_cfg);
			eep_obj.read_req --;
		}
		
		if(eep_obj.save_req)
		{
			loop_n(11)
				eep_obj.dat[index] = index + eep_obj.dat_start;
			
			ExtFlashMulEepSave(&ext_eep_cfg);
			
			eep_obj.dat_start ++;
			eep_obj.save_req --;
		}
		
		if(eep_obj.m_read_req)
		{
			eep_obj.m_read_req--;
			FlashMulEepRead(&mfe_cfg);
		}
		
		if(eep_obj.m_save_req)
		{
			loop_n(11)
				eep_obj.dat[index] = index + eep_obj.dat_start;
			
			FlashMulEepSave(&mfe_cfg);
			
			eep_obj.dat_start ++;
			eep_obj.m_save_req --;
		}
		
		osDelay(10);
	}
}


/*--------------------------------------------------------------------------------*
* log buff hal
*---------------------------------------------------------------------------------*/
uint8_t ExtEepProgram(uint32_t Addr, uint8_t *Data, uint16_t Len)
{
	dword_tt datw;
	
	SYS_UnlockReg();
	FMC_Open();
	FMC_ENABLE_AP_UPDATE();

	loop_n(Len)
	{
		if((index & 3) == 0)
			datw.uval = UINT32_MAX;
		
		datw.v[index & 3] = *Data++;
		
		if((index & 3) == 3)
		{
			FMC_Write(Addr, datw.uval);
			Addr += 4;
		}
	}

	if(Len & 0x03)
	{
		FMC_Write(Addr, datw.uval);
	}
	
	FMC_DISABLE_AP_UPDATE();
	FMC_Close();
	SYS_LockReg();
	
	return 0;
}

uint8_t ExtEepRead(uint32_t Addr, uint8_t *Data, uint16_t Len)
{
	copy_u8((void *)Addr, Data, Len);
	
	return 0;
}

uint8_t ExtEepErase(uint32_t AddrBase)
{
	SYS_UnlockReg();
	FMC_Open();
	FMC_ENABLE_AP_UPDATE();

	FMC_Erase(AddrBase);

	FMC_DISABLE_AP_UPDATE();
	FMC_Close();
	SYS_LockReg();
	
	return 0;
}


void feep_erase(uint32_t addr)
{
	FMC_Erase(addr);
}

void feep_program(uint32_t addr, uint32_t dat)
{
	FMC_Write(addr, dat);
}

void feep_unlock(void)
{
	SYS_UnlockReg();
	FMC_Open();
	FMC_ENABLE_AP_UPDATE();
}

void feep_lock(void)
{
	FMC_DISABLE_AP_UPDATE();
	FMC_Close();
	SYS_LockReg();
}